﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon;
using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using DevToolBox.Cloud.Common;
using DevToolBox.Common;

namespace DevToolBox.Cloud.Amazon
{
    public class AmazonIdentityManagement : IManageable
    {
        private AmazonIdentityManagementServiceClient aimClient = null;
        private AmazonIdentityManagementServiceConfig aimConfig = null;

        public AmazonIdentityManagement()
        {
            aimConfig = new AmazonIdentityManagementServiceConfig();
            aimConfig.UseSecureStringForAwsSecretKey = false;
            aimClient = new AmazonIdentityManagementServiceClient(aimConfig);
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        private void CreateUser(string userName)
        {
            //Creates a user only if does not exist
            if (GetUser(userName) == null)
            {
                CreateUserRequest createReq = new CreateUserRequest();
                createReq.UserName = userName;
                aimClient.CreateUser(createReq);
            }
        }

        private string GetUser(string userName)
        {
            //Gets an user only if does exist
            GetUserRequest getReq = new GetUserRequest();
            getReq.UserName = userName;
            GetUserResponse getResponse = null;

            try
            {
                getResponse = aimClient.GetUser(getReq);
            }
            catch { }

            if (getResponse == null || getResponse.GetUserResult == null ||
                getResponse.GetUserResult.User == null)
            {
                return null;
            }
            else
            {
                return getResponse.GetUserResult.User.UserName;
            }
        }

        public string GetStatus(string keyVal)
        {
            //Get the access key status only if the user does exist
            string userName = keyVal;
            if (GetUser(userName) == null)
            {
                return null;
            }
            else
            {                
                var accessKeysReq = new ListAccessKeysRequest();
                accessKeysReq.UserName = userName;
                accessKeysReq.MaxItems = 1;
                ListAccessKeysResponse keys = aimClient.ListAccessKeys(accessKeysReq);

                string accessKeyId = null;
                if (keys != null && keys.ListAccessKeysResult != null &&
                    keys.ListAccessKeysResult != null && keys.ListAccessKeysResult.AccessKeyMetadata.Count > 0)
                {
                    var keyObj = keys.ListAccessKeysResult.AccessKeyMetadata[0];
                    accessKeyId = keyObj.AccessKeyId;
                }
                return accessKeyId;
            }
        }

        public void Create(object configObject)
        {
            string[] keys = (string[])configObject;
            string userName = keys[0];

            if (GetStatus(userName) == null)
            {
                var createUserReq = new CreateUserRequest();
                createUserReq.UserName = userName;
                var createUserRes = aimClient.CreateUser(createUserReq);

                if (createUserRes != null && createUserRes.CreateUserResult != null &&
                    createUserRes.CreateUserResult.User != null)
                {
                    var createAccessKeyReq = new CreateAccessKeyRequest();
                    createAccessKeyReq.UserName = userName;
                    var accessKeyRequest = aimClient.CreateAccessKey(createAccessKeyReq);
                    string accessKey = accessKeyRequest.CreateAccessKeyResult.AccessKey.AccessKeyId;
                    string secretKey = accessKeyRequest.CreateAccessKeyResult.AccessKey.SecretAccessKey;
                    keys[1] = accessKey;
                    keys[2] = secretKey;
                }
            }
        }

        public void Delete(string key)
        {
            string userName = key;
            string accessKeyId = GetStatus(userName);

            if (accessKeyId != null)
            {
                DeleteAccessKeyRequest deleteKeyReq = new DeleteAccessKeyRequest();
                deleteKeyReq.UserName = userName;
                deleteKeyReq.AccessKeyId = accessKeyId;
                aimClient.DeleteAccessKey(deleteKeyReq);

                DeleteUserRequest deleteUserReq = new DeleteUserRequest();
                deleteUserReq.UserName = userName;
                DeleteUserResponse deleteUserRes = aimClient.DeleteUser(deleteUserReq);

                if (deleteUserRes == null || deleteUserRes.ResponseMetadata == null ||
                    deleteUserRes.ResponseMetadata.RequestId == null)
                {
                    throw new Exception("[DevToolBox.Cloud.Amazon.AmazonIdentityManagement.Delete] Error deleting an AWS Access Key");
                }
            }
        }

        public void Update(object configObject)
        {
            //This operation is not needed yet
            throw new NotImplementedException();
        }
    }
}